home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / ODF / Internet / FWCyPart.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  35.4 KB  |  1,049 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWCyPart.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //    Support for FW_OCyberPartExtension. Wraps it so that the developer
  9. //    never needs to deal with SOM. Also implements basic recipes.
  10. //
  11. //========================================================================================
  12.  
  13. #ifndef FWFRAMEW_HPP
  14. #include "FWFrameW.hpp"
  15. #endif
  16.  
  17. #ifndef FWCYPART_H
  18. #include "FWCyPart.h"
  19. #endif
  20.  
  21. #ifndef FWCYSTRM_H
  22. #include "FWCyStrm.h"
  23. #endif
  24.  
  25. #ifndef FWMNUBAR_H
  26. #include "FWMnuBar.h"
  27. #endif
  28.  
  29. #ifndef SLCYUTIL_H
  30. #include "SLCyUtil.h"
  31. #endif
  32.  
  33. #ifndef FWPART_H
  34. #include "FWPart.h"
  35. #endif
  36.  
  37. #ifndef FWFRAME_H
  38. #include "FWFrame.h"
  39. #endif
  40.  
  41. #ifndef FWEXTMGR_H
  42. #include "FWExtMgr.h"
  43. #endif
  44.  
  45. #ifndef FWITERS_H
  46. #include "FWIters.h"
  47. #endif
  48.  
  49. #ifndef FWODTHRD_H
  50. #include "FWODThrd.h"
  51. #endif
  52.  
  53. #ifndef FWSOMENV_H
  54. #include "FWSOMEnv.h"
  55. #endif
  56.  
  57. //
  58. // Cyberdog
  59. //
  60.  
  61. #ifndef __CYBERDOG__
  62. #include <Cyberdog.h>
  63. #endif
  64.  
  65. #ifndef SOM_CyberSession_xh
  66. #include <CyberSession.xh>
  67. #endif
  68.  
  69. #ifndef SOM_CyberProgressBroadcaster_xh
  70. #include <CyberProgressBroadcaster.xh>
  71. #endif
  72.  
  73. #ifndef SOM_CyberOpenerPartExtension_xh
  74. #include <CyberOpenerPartExtension.xh>
  75. #endif
  76.  
  77. #ifndef SOM_CyberNavigatorExtension_xh
  78. #include <CyberNavigatorExtension.xh>
  79. #endif
  80.  
  81. #ifndef SOM_CyberServiceMenu_xh
  82. #include <CyberServiceMenu.xh>
  83. #endif
  84.  
  85. #ifndef SOM_CyberStream_xh
  86. #include <CyberStream.xh>
  87. #endif
  88.  
  89. //-----------------------------------------------------------------------------
  90. // FW_TOrderedCollection Runtime Information
  91. //-----------------------------------------------------------------------------
  92. #pragma mark FW_TOrderedCollection Runtime Information
  93.  
  94. #include "FWTColl.tpp"
  95.  
  96. typedef FW_TOrderedCollectionIterator<FW_CThread> FW_CThreadsCollectionIterator;
  97.  
  98. FW_DEFINE_AUTO_TEMPLATE (FW_TOrderedCollection, FW_CThread)
  99. FW_DEFINE_AUTO_TEMPLATE (FW_TOrderedCollectionIterator, FW_CThread)
  100.  
  101. #ifdef FW_USE_TEMPLATE_PRAGMAS
  102.     #pragma template_access public
  103.     #pragma template FW_TOrderedCollection<FW_CThread>
  104.     #pragma template FW_TOrderedCollectionIterator<FW_CThread>
  105. #else
  106.     template class FW_TOrderedCollection<FW_CThread>;
  107.     template class FW_TOrderedCollectionIterator<FW_CThread>;
  108. #endif
  109.  
  110. #pragma mark -
  111. //========================================================================================
  112. // Class FW_TObjectSafety
  113. //========================================================================================
  114. #pragma mark Class FW_TObjectSafety
  115.  
  116. /*
  117.     FW_TObjectSafety is a smart pointer object. It's reusable and should be put
  118.     in its own file somewhere.
  119.     
  120.     Semantics:
  121.         FW_TObjectSafety()        Assumes ownership of the object.
  122.         ~FW_TObjectSafety()        Deletes its object.
  123.         Release()                Returns its object; no longer owns it.
  124.         No copy construction permitted. No assignment permitted.        
  125. */
  126.  
  127.  
  128. template <class T>
  129. class FW_TObjectSafety {
  130. public:
  131.                     FW_DECLARE_AUTO (FW_TObjectSafety)
  132.                     FW_TObjectSafety (T* object);
  133.                     ~FW_TObjectSafety ();
  134.     T*                 Release ();
  135. private:
  136.                     FW_TObjectSafety (const FW_TObjectSafety<T>& )    {}
  137.     void             operator= (const FW_TObjectSafety<T>& )            {}
  138. private:
  139.     T*                 fObject;
  140. };
  141.  
  142. //-----------------------------------------------------------------------------
  143. // FW_TObjectSafety Runtime Information
  144. //-----------------------------------------------------------------------------
  145.  
  146. #ifdef FW_BUILD_MAC
  147. #pragma segment FWInternet
  148. #endif
  149.  
  150. //-----------------------------------------------------------------------------
  151. // FW_TObjectSafety<T>::FW_TObjectSafety
  152. //-----------------------------------------------------------------------------
  153.  
  154. template <class T>
  155. FW_TObjectSafety<T>::FW_TObjectSafety (T* object)
  156. :    fObject (object)
  157. {
  158.     FW_END_CONSTRUCTOR
  159. }
  160.  
  161. //-----------------------------------------------------------------------------
  162. // FW_TObjectSafety<T>::~FW_TObjectSafety
  163. //-----------------------------------------------------------------------------
  164.  
  165. template <class T>
  166. FW_TObjectSafety<T>::~FW_TObjectSafety ()
  167. {
  168.     FW_START_DESTRUCTOR
  169.     delete fObject;
  170. }
  171.  
  172. //-----------------------------------------------------------------------------
  173. // FW_TObjectSafety<T>::Release
  174. //-----------------------------------------------------------------------------
  175.  
  176. template <class T>
  177. T* FW_TObjectSafety<T>::Release ()
  178. {
  179.     T* temporary = fObject;
  180.     fObject = 0;
  181.     return temporary;
  182. }
  183.  
  184. //-----------------------------------------------------------------------------
  185. // FW_TObjectSafety Runtime Information
  186. //-----------------------------------------------------------------------------
  187. #pragma mark FW_TObjectSafety Runtime Information
  188.  
  189. #ifdef FW_USE_TEMPLATE_PRAGMAS
  190. #pragma template_access public
  191. #pragma template FW_TObjectSafety<FW_CThread>
  192. #pragma template FW_TObjectSafety<FW_CCyberdogHelper>
  193. #endif
  194.  
  195. FW_DEFINE_AUTO_TEMPLATE (FW_TObjectSafety, FW_CThread)
  196. FW_DEFINE_AUTO_TEMPLATE (FW_TObjectSafety, FW_CCyberdogHelper)
  197.  
  198. #pragma mark -
  199. //========================================================================================
  200. // Callback Prototypes
  201. //========================================================================================
  202. #pragma mark Callback Prototypes
  203.  
  204. /*
  205.     We fill in a struct with pointers to these functions, and pass it to the
  206.     extension. When it calls them, it passes in a pointer to that struct.
  207.     We've subclassed the struct, so we just cast it to a pointer
  208.     to our real C++ classes, and call equivalent virtual methods for
  209.     each function.
  210. */
  211.  
  212. void         FW_CallbackOpenCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*, ODPart*, ParameterSet*);
  213. void         FW_CallbackSetCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*, ParameterSet*);
  214. ODBoolean     FW_CallbackCanShowCyberItem        (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  215. void         FW_CallbackShowCyberItem         (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  216. ODWindow*      FW_CallbackGetCyberItemWindow     (Environment*, FW_SCyberPartExtensionCallbacks*, CyberItem*);
  217. ODBoolean     FW_CallbackIsCyberItemSelected     (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*);
  218. void         FW_CallbackAcquireSelectedCyberItems (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*, CyberItemList*);
  219. ODBoolean    FW_CallbackIsURLSelected         (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*);
  220. void         FW_CallbackGetSelectedURL         (Environment*, FW_SCyberPartExtensionCallbacks*, ODFrame*, FW_CString& url);
  221. ODBoolean     FW_CallbackHandleCommand         (Environment*, FW_SCyberPartExtensionCallbacks*, long, long, ODFrame*, somToken);
  222.  
  223. #pragma mark -
  224. //========================================================================================
  225. // SOM Utilities
  226. //========================================================================================
  227. #pragma mark SOM Utilities
  228.  
  229. /*
  230.     Since we have a SOM interface, we have to make sure we don't try to
  231.     throw any C++ exceptions out of here; we need to catch them and convert
  232.     them into SOM exceptions.
  233. */
  234.  
  235. static const char FW_kInvalidException[] = "Unknown Exception!"; 
  236.  
  237. #define FW_SOM_CALLBACK_TRY            \
  238.     FW_TRY                            \
  239.     {
  240.  
  241. #define FW_SOM_CALLBACK_ENDTRY        \
  242.     }                                \
  243.     FW_CATCH_BEGIN                    \
  244.     FW_CATCH_REFERENCE(FW_XException, exception)\
  245.     {                                \
  246.         FW_SetException(ev, exception);\
  247.     }                                \
  248.     FW_CATCH_EVERYTHING()            \
  249.     {                                \
  250.         FW_DEBUG_MESSAGE(FW_kInvalidException);\
  251.         FW_SetEvError(ev, kODErrUndefined);\
  252.     }                                \
  253.     FW_CATCH_END
  254.  
  255. #pragma mark -
  256. //-----------------------------------------------------------------------------
  257. // FW_SupportCyberdogIfPresent
  258. //-----------------------------------------------------------------------------
  259.  
  260. FW_CCyberdogHelper* FW_SupportCyberdogIfPresent (Environment* ev, FW_CPart* part, FW_Boolean cymenus, ODCommandID cybase, FW_Boolean cynav)
  261. {
  262.     if (!FW_CyberdogIsInstalled (ev))
  263.         return kODNULL;
  264.     
  265.     FW_CCyberdogHelper* helper = FW_NEW (FW_CCyberdogHelper, (part));
  266.     FW_TObjectSafety<FW_CCyberdogHelper> helperSafety (helper);
  267.     helper->Initialize (ev, cymenus, cybase, cynav);
  268.     part->AdoptEventHandler (ev, helper);
  269.     helperSafety.Release();
  270.     return helper;
  271. }
  272.  
  273. #pragma mark -
  274. //========================================================================================
  275. // Class FW_CCyberdogHelper
  276. //========================================================================================
  277. #pragma mark Class FW_CCyberdogHelper
  278.  
  279. //-----------------------------------------------------------------------------
  280. // FW_CCyberdogHelper Globals
  281. //-----------------------------------------------------------------------------
  282.  
  283. RoutineDescriptor FW_kCyberAbortTaskUPP = BUILD_ROUTINE_DESCRIPTOR (uppCyberAbortProcInfo, FW_CCyberdogHelper::PrivCyberAbort);
  284.  
  285. //-----------------------------------------------------------------------------
  286. // FW_CCyberdogHelper Runtime Information
  287. //-----------------------------------------------------------------------------
  288. #pragma mark FW_CCyberdogHelper Runtime Information
  289.  
  290. FW_DEFINE_AUTO (FW_CCyberdogHelper)
  291.  
  292. //-----------------------------------------------------------------------------
  293. // FW_CCyberdogHelper::FW_CCyberdogHelper
  294. //-----------------------------------------------------------------------------
  295.  
  296. FW_CCyberdogHelper::FW_CCyberdogHelper (FW_CPart* part)
  297. :    FW_CCyberdogCallbacks (part)
  298. ,    fCyberServiceMenu (kODNULL)
  299. ,    fUseNavigator (false)
  300. ,    fCyberdogMenuHandle (kODNULL)
  301. ,    fLoadCyberItemThreadProcedure (0)
  302. ,    fLoadCyberItemThreadParameters (0)
  303. {
  304.     FW_END_CONSTRUCTOR
  305. }
  306.  
  307. //-----------------------------------------------------------------------------
  308. // FW_CCyberdogHelper::~FW_CCyberdogHelper
  309. //-----------------------------------------------------------------------------
  310.  
  311. FW_CCyberdogHelper::~FW_CCyberdogHelper ()
  312. {
  313.     FW_START_DESTRUCTOR
  314.     
  315.     //
  316.     // Menu Support
  317.     //
  318.     
  319.     if (fCyberdogMenuHandle)
  320.         ::DisposeHandle (fCyberdogMenuHandle);
  321.     delete fCyberServiceMenu;
  322.     
  323.     //
  324.     // Thread Support
  325.     //
  326.     
  327.     FW_CThreadsCollectionIterator threads (&fThreads);
  328.     for (FW_CThread* task = threads.First(); threads.IsNotComplete(); task = threads.Next() )
  329.         delete task;
  330. }
  331.  
  332. //-----------------------------------------------------------------------------
  333. // FW_CCyberdogHelper::Initialize
  334. //-----------------------------------------------------------------------------
  335.  
  336. void FW_CCyberdogHelper::Initialize (Environment* ev, FW_Boolean cymenus, ODCommandID cybase, FW_Boolean cynav)
  337. {
  338.     FW_CCyberdogCallbacks::Initialize (ev);
  339.     
  340.     FW_CPart* part = GetPart();
  341.     
  342.     // Even if we don't want the Cyberdog service menus, we should use the Cyberdog Document
  343.     // menu if we are in the memory draft. We don't need to check; Install... does.
  344.     FW_TAcquiredODRefCntObject<ODMenuBar> menus = part->GetMenuBar(ev)->AcquireODMenuBar(ev);
  345.     fCyberdogMenuHandle = GetCyberSession (ev)->InstallCyberDocumentMenu (ev, part->GetODPart(ev), menus);
  346.     
  347.     // Cyberdog service menus take up lots of space and aren't always desirable.
  348.     if (cymenus) {
  349.         fCyberCommands = cybase;
  350.         fCyberServiceMenu = new CyberServiceMenu;
  351.         fCyberServiceMenu->ICyberServiceMenu (ev, menus, part->GetODPart(ev), cybase);
  352.     }
  353.     
  354.     // Ok, do we want to show up in a navigator part?
  355.     if (cynav)
  356.         fUseNavigator = true;
  357. }
  358.  
  359. /*
  360.     Threads Support
  361. */
  362.  
  363. //-----------------------------------------------------------------------------
  364. // FW_CCyberdogHelper::SetLoadCyberItemThreadProcedure
  365. //-----------------------------------------------------------------------------
  366.  
  367. void 
  368. FW_CCyberdogHelper::SetLoadCyberItemThreadProcedure (FW_ThreadProcedure loadCyberItem, void* parameters)
  369. {
  370.     // See DoSetCyberItem
  371.     fLoadCyberItemThreadProcedure = loadCyberItem;
  372.     fLoadCyberItemThreadParameters = parameters;
  373. }
  374.  
  375. //-----------------------------------------------------------------------------
  376. // FW_CCyberdogHelper::DoSetCyberItem
  377. //-----------------------------------------------------------------------------
  378.  
  379. void FW_CCyberdogHelper::DoSetCyberItem (Environment* ev, CyberItem* newItem, ParameterSet* parameters)
  380. {
  381.     FW_UNUSED (ev);
  382.     FW_UNUSED (newItem);
  383.     FW_UNUSED (parameters);
  384.     
  385.     // Should be customized by Developer
  386.     // Must call inherited (done in extension)
  387.     
  388.     // mlanett 6/21/96 Threads Support
  389.     // Now you can install a callback function and when Cyberdog wants
  390.     // you to load something, the framework will create a thread and run the
  391.     // function. Allows you to do the standard customization of FW_CCyberdogHelper 
  392.     // without having to subclass it or mix it into your part.
  393.     if (fLoadCyberItemThreadProcedure) {
  394.         FW_CThread* task = new FW_CThread (fLoadCyberItemThreadParameters, fLoadCyberItemThreadProcedure);
  395.         FW_TObjectSafety<FW_CThread> taskSafety (task);
  396.         fThreads.AddLast (task);
  397.         taskSafety.Release();
  398.     }
  399.     else
  400.         FW_ASSERT (("FW_CCyberdogHelper::DoSetCyberItem - you should either install a callback or override!", false));
  401. }
  402.     
  403. /*
  404.     CloseCyberDraftWindow & Cyberdog Menus Support
  405. */
  406.  
  407. //-----------------------------------------------------------------------------
  408. // FW_CCyberdogHelper::DoMenu
  409. //-----------------------------------------------------------------------------
  410.  
  411. FW_Handled FW_CCyberdogHelper::DoMenu (Environment* ev, const FW_CMenuEvent& event)
  412. {
  413.     ODBoolean handled = FALSE;
  414.     ODCommandID id = event.GetCommandID(ev);
  415.     
  416.     FW_CPart* part = GetPart();
  417.     ODPart* odpart = part->GetODPart (ev);
  418.     FW_CFrame* probableFrame = part->GetLastActiveFrame(ev); // XXX really really need to get the proper frame!
  419.     
  420.     if (fCyberServiceMenu && (fCyberCommands <= id) && (id < (fCyberCommands+1000)))
  421.         handled = fCyberServiceMenu->DoCommand (ev, event.GetCommandID(ev), probableFrame->GetODFrame(ev));
  422.     
  423.     if (!handled && id == kODCommandClose && probableFrame->IsRoot(ev)) {
  424.     /*    FW_CWindow* window = frame->GetWindow(ev);*/
  425.         /*if (!window->IsFloating())*/ {
  426.             CyberSession* cyberSession = GetExtension (ev)->GetCyberSession (ev);
  427.             handled = cyberSession->CloseCyberDraftWindow (ev, odpart);
  428.         }
  429.     }
  430.     
  431.     return handled ? FW_kHandled : FW_kNotHandled;
  432. }
  433.  
  434. //-----------------------------------------------------------------------------
  435. // FW_CCyberdogHelper::DoAdjustMenus
  436. //-----------------------------------------------------------------------------
  437.  
  438. FW_Handled FW_CCyberdogHelper::DoAdjustMenus (Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
  439. {
  440.     FW_UNUSED (menuBar);
  441.     FW_UNUSED (isRoot);
  442.     
  443.     // Damnit, the frame isn't passed in here. 
  444.     // Hopefully ActiveFrame will be the frame with the menu focus.
  445.     if (hasMenuFocus && fCyberServiceMenu) {
  446.         FW_CPart* part = GetPart();
  447.         FW_CFrame* probableFrame = part->GetLastActiveFrame(ev);
  448.         fCyberServiceMenu->Adjust (ev, probableFrame->GetODFrame(ev));
  449.     }
  450.     
  451.     return FW_kNotHandled;
  452. }
  453.  
  454. /*
  455.     CyberItem Utilities
  456. */
  457.  
  458. //-----------------------------------------------------------------------------
  459. // FW_CCyberdogHelper::GetCyberItem
  460. //-----------------------------------------------------------------------------
  461.  
  462. CyberItem* 
  463. FW_CCyberdogHelper::GetCyberItem (Environment* ev)
  464. {
  465.     return GetExtension (ev)->GetCyberItem (ev);
  466. }
  467.  
  468. //-----------------------------------------------------------------------------
  469. // FW_CCyberdogHelper::GetCyberSession
  470. //-----------------------------------------------------------------------------
  471.  
  472. CyberSession* 
  473. FW_CCyberdogHelper::GetCyberSession (Environment* ev)
  474. {
  475.     // Having a CyberSession is equivalent to having the extension.
  476.     CyberPartExtension* extension = GetExtension(ev);
  477.     return extension?
  478.         extension->GetCyberSession (ev):
  479.         ::GetCyberSession(ev); // XXX CD bug sometimes returns null
  480. }
  481.  
  482. //-----------------------------------------------------------------------------
  483. // FW_CCyberdogHelper::InternalizeCyberItem
  484. //-----------------------------------------------------------------------------
  485.  
  486. CyberItem* 
  487. FW_CCyberdogHelper::InternalizeCyberItem (Environment* ev, FW_OSink* sink, Boolean reload)
  488. {
  489.     // Cyberdog must be installed. If Cyberdog is not loaded, it will be.
  490.     CyberItem* ci = kODNULL;
  491.     
  492.     ci = FW_ReadCyberItem (ev, GetCyberSession (ev), sink);
  493.     if (reload)
  494.         GetExtension (ev)->SetCyberItem (ev, ci, kODNULL);
  495.     
  496.     return ci;
  497. }
  498.  
  499. //-----------------------------------------------------------------------------
  500. // FW_CCyberdogHelper::ExternalizeCurrentCyberItem
  501. //-----------------------------------------------------------------------------
  502.  
  503. void 
  504. FW_CCyberdogHelper::ExternalizeCurrentCyberItem (Environment* ev, FW_OSink* sink)
  505. {
  506.     CyberItem* ci = GetCyberItem (ev);
  507.     if (ci) {
  508.         FW_WriteCyberItem (ev, ci, sink);
  509.     }
  510. }
  511.  
  512. /*
  513.     Navigator support
  514. */
  515.  
  516. //-----------------------------------------------------------------------------
  517. // FW_CCyberdogHelper::HandleOpenCyberItem
  518. //-----------------------------------------------------------------------------
  519.  
  520. void FW_CCyberdogHelper::HandleOpenCyberItem (Environment* ev, CyberItem* item, ODPart* openerPart, ParameterSet* parameters)
  521. {
  522.     // By default call the default ("inherited") OpenCyberItem in CyberPartExtension.
  523.     if (!fUseNavigator) {
  524.         FW_CCyberdogCallbacks::HandleOpenCyberItem (ev, item, openerPart, parameters);
  525.         return;
  526.     }
  527.     
  528.     // OpenCyberItem by default opens a little progress window and then our 
  529.     // part by itself. We want to show up in a browser ("Navigator"); this will
  530.     // require us to replace this method.
  531.     
  532.     GetExtension (ev)->SetCyberItem (ev, item, parameters);
  533.     // The extension will call our DoSetCyberItem and we will...
  534.     // 1) hook up the progress bar
  535.     // 2) start reading the data from the network
  536.     
  537.     // Now then, are we already in a navigator part ("browsing in place") or do
  538.     // we need to create one?
  539.     
  540.     FW_TAcquiredODRefCntObject<ODPart> navigator;
  541.     if (openerPart && openerPart->HasExtension (ev, kCyberNavigatorExtension)) {
  542.         // FW_TAcquiredODRefCntObject does not acquire its objects; it only releases them.
  543.         // Normally acquisition is performed by the accessor function but in this case 
  544.         // openerPart was passed in to us.
  545.         openerPart->Acquire(ev);
  546.         navigator = openerPart;
  547.     }
  548.     else {
  549.         navigator = GetCyberSession(ev)->CreateCyberPart (ev, openerPart, kNavigatorKind, kODNULL);
  550.         if (openerPart && openerPart->HasExtension (ev, kCyberOpenerPartExtension)) {
  551.             FW_TAcquiredODRefCntObject<CyberOpenerPartExtension> cope = (CyberOpenerPartExtension*) openerPart->AcquireExtension (ev, kCyberOpenerPartExtension);
  552.             cope->OpenPart (ev, item, navigator, parameters);
  553.         }
  554.         else
  555.             navigator->Open (ev, kODNULL);
  556.     }
  557.     
  558.     // Finally make sure the navigator displays us (navigators have lots of 
  559.     // parts but only show one at a time in their frames).
  560.     
  561.     if (navigator->HasExtension (ev, kCyberNavigatorExtension)) {
  562.         FW_CPart* part = GetPart();
  563.         FW_TAcquiredODRefCntObject<CyberNavigatorExtension> nave = (CyberNavigatorExtension*) navigator->AcquireExtension (ev, kCyberNavigatorExtension);
  564.         nave->GoToCyberItem (ev, item, part->GetODPart(ev), parameters);
  565.     }
  566. }
  567.  
  568. //-----------------------------------------------------------------------------
  569. // FW_CCyberdogHelper::AcquireContainingNavigator
  570. //-----------------------------------------------------------------------------
  571.  
  572. ODPart* FW_CCyberdogHelper::AcquireContainingNavigator (Environment* ev)
  573. {
  574.     CyberSession* session = GetCyberSession (ev);
  575.     if (!session)
  576.         return kODNULL;
  577.     
  578.     // It's remotely possible to be embedded in multiple navigators, but they
  579.     // would all be the same, so it's not a problem. Just find the first navigator
  580.     // containing a frame.
  581.     
  582.     FW_CPart* part = GetPart();
  583.     FW_CFrame* probableFrame = part->GetLastActiveFrame(ev);
  584.     if (!probableFrame)
  585.         return kODNULL;
  586.     FW_CPresentationFrameIterator fiter (ev, probableFrame->GetPresentation (ev));
  587.     for (FW_CFrame* f = fiter.First(ev); fiter.IsNotComplete(ev); f = fiter.Next(ev)) {
  588.         ODPart* navigator = session->AcquireContainingNavigatorPart (ev, f->GetODFrame(ev));
  589.         if (navigator)
  590.             return navigator;
  591.     }
  592.     
  593.     return kODNULL;
  594. }
  595.  
  596. //-----------------------------------------------------------------------------
  597. // FW_CCyberdogHelper::MakeCyberProgressBroadcaster
  598. //-----------------------------------------------------------------------------
  599.  
  600. CyberProgressBroadcaster* FW_CCyberdogHelper::MakeCyberProgressBroadcaster (Environment* ev, short mode)
  601. {
  602.     CyberProgressBroadcaster* broadcaster = new CyberProgressBroadcaster;
  603.     broadcaster->ICyberProgressBroadcaster (ev, &FW_kCyberAbortTaskUPP, (Ptr)this);
  604.     // kUnmeteredProgress
  605.     broadcaster->SetProgressMode(ev, mode);
  606.     return broadcaster;
  607. }
  608.  
  609. //-----------------------------------------------------------------------------
  610. // FW_CCyberdogHelper::DoCyberAbort
  611. //-----------------------------------------------------------------------------
  612.  
  613. void FW_CCyberdogHelper::DoCyberAbort (Environment* ev, CyberProgressBroadcaster* broadcaster)
  614. {
  615.     FW_UNUSED (ev);
  616.     
  617.     delete broadcaster;
  618. }
  619.  
  620. //-----------------------------------------------------------------------------
  621. // FW_CCyberdogHelper::PrivCyberAbort
  622. //-----------------------------------------------------------------------------
  623.  
  624. void FW_CCyberdogHelper::PrivCyberAbort (CDAbortProcMessage message, CyberProgressBroadcaster* broadcaster, Ptr selfPtr)
  625. {
  626.     FW_SOMEnvironment ev;
  627.     FW_CCyberdogHelper* self = (FW_CCyberdogHelper*) selfPtr;
  628.     
  629.     switch (message) {
  630.         case kAbortMessage:
  631.             self->DoCyberAbort (ev, broadcaster);
  632.             break;
  633.         default:
  634.             break;
  635.     }
  636. }
  637.  
  638. #pragma mark -
  639. //========================================================================================
  640. // Class FW_CCyberdogCallbacks
  641. //========================================================================================
  642. #pragma mark Class FW_CCyberdogCallbacks
  643.  
  644. //-----------------------------------------------------------------------------
  645. // FW_CCyberdogCallbacks Globals
  646. //-----------------------------------------------------------------------------
  647.  
  648. FW_DEFINE_AUTO (FW_CCyberdogCallbacks)
  649.  
  650. //-----------------------------------------------------------------------------
  651. // FW_CCyberdogCallbacks::FW_CCyberdogCallbacks
  652. //-----------------------------------------------------------------------------
  653.  
  654. FW_CCyberdogCallbacks::FW_CCyberdogCallbacks (FW_CPart* part)
  655. :    fPart (part)
  656. ,    fExtension (0)
  657. {
  658.     openCyberItem =         &FW_CallbackOpenCyberItem;
  659.     setCyberItem =             &FW_CallbackSetCyberItem;
  660.     canShowCyberItem =         &FW_CallbackCanShowCyberItem;
  661.     showCyberItem =         &FW_CallbackShowCyberItem;
  662.     getCyberItemWindow =     &FW_CallbackGetCyberItemWindow;
  663.     isCyberItemSelected =     &FW_CallbackIsCyberItemSelected;
  664.     acquireSelectedCyberItems = &FW_CallbackAcquireSelectedCyberItems;
  665.     isURLSelected =         &FW_CallbackIsURLSelected;
  666.     getSelectedURL =         &FW_CallbackGetSelectedURL;
  667.     handleCommand =         &FW_CallbackHandleCommand;
  668.     
  669.     FW_END_CONSTRUCTOR
  670. }
  671.  
  672. //-----------------------------------------------------------------------------
  673. // FW_CCyberdogCallbacks::~FW_CCyberdogCallbacks
  674. //-----------------------------------------------------------------------------
  675.  
  676. FW_CCyberdogCallbacks::~FW_CCyberdogCallbacks ()
  677. {
  678.     FW_START_DESTRUCTOR
  679. }
  680.  
  681. //-----------------------------------------------------------------------------
  682. // FW_CCyberdogCallbacks::Initialize
  683. //-----------------------------------------------------------------------------
  684.  
  685. void FW_CCyberdogCallbacks::Initialize (Environment* ev)
  686. {
  687.     // Register our extension
  688.     FW_CExtensionManager* manager = fPart->GetExtensionManager(ev);
  689.     FW_ASSERT (manager);
  690.     manager->RegisterExtension (ev, kCyberPartExtension, &CreateCyberExtension, this, FALSE);
  691. }
  692.  
  693. //-----------------------------------------------------------------------------
  694. // FW_CCyberdogCallbacks::GetExtension
  695. //-----------------------------------------------------------------------------
  696.  
  697. CyberPartExtension* FW_CCyberdogCallbacks::GetExtension (Environment* ev)
  698. {
  699.     // Possibilities:
  700.     // (a) We don't have Cyberdog installed. In that case this object should 
  701.     // not be created in the first place: if (FW_HasCyberdog()) { // create
  702.     // (b) Have Cyberdog but we don't want its menus or navigator and it
  703.     // hasn't invoked us (i.e. we are a normal part).
  704.     // (c) Have Cyberdog and have its menus or other such.
  705.      
  706.     // We don't want to load Cyberdog if it's not necessary. Cyberdog will be loaded if:
  707.     // (a) We use Cyberdog menus or the navigator
  708.     // (b) We call GetExtension()
  709.     // (c) Cyberdog calls us.
  710.     
  711.     // To avoid loading Cyberdog (if it's not loaded and you don't NEED it), 
  712.     // call CyberdogIsLoaded.
  713.     
  714.     FW_Boolean create = true;
  715.     FW_CAcquiredODFCyberPartExtension extension = (ODF_FW_OCyberPartExtension*) fPart->GetExtensionManager(ev)->AcquireExtension (ev, kCyberPartExtension, create);
  716.     return extension;
  717. }
  718.  
  719. //-----------------------------------------------------------------------------
  720. // FW_CCyberdogCallbacks::CyberdogIsLoaded
  721. //-----------------------------------------------------------------------------
  722.  
  723. FW_Boolean FW_CCyberdogCallbacks::CyberdogIsLoaded (Environment* ev)
  724. {
  725.     FW_Boolean create = false;
  726.     FW_CAcquiredODFCyberPartExtension extension = (ODF_FW_OCyberPartExtension*) fPart->GetExtensionManager(ev)->AcquireExtension (ev, kCyberPartExtension, create);
  727.     return extension != kODNULL;
  728. }
  729.  
  730. /*
  731.     Cyberdog Callbacks
  732. */
  733.  
  734. //-----------------------------------------------------------------------------
  735. // FW_CCyberdogCallbacks::HandleOpenCyberItem
  736. //-----------------------------------------------------------------------------
  737.  
  738. void FW_CCyberdogCallbacks::HandleOpenCyberItem (Environment* ev, CyberItem* item, ODPart* openerPart, ParameterSet* parameters)
  739. {
  740.     // By default call the default ("inherited") OpenCyberItem in CyberPartExtension.
  741.     fExtension->DefaultOpenCyberItem (ev, item, openerPart, parameters);
  742. }
  743.  
  744. //-----------------------------------------------------------------------------
  745. // FW_CCyberdogCallbacks::DoSetCyberItem
  746. //-----------------------------------------------------------------------------
  747.  
  748. void FW_CCyberdogCallbacks::DoSetCyberItem (Environment* ev, CyberItem* newItem, ParameterSet* parameters)
  749. {
  750.     FW_UNUSED (ev);
  751.     FW_UNUSED (newItem);
  752.     FW_UNUSED (parameters);
  753.     
  754.     // Should be customized by Developer
  755.     // Must call inherited (done in extension)
  756. }
  757.     
  758. //-----------------------------------------------------------------------------
  759. // FW_CCyberdogCallbacks::DoCanShowCyberItem
  760. //-----------------------------------------------------------------------------
  761.  
  762. ODBoolean FW_CCyberdogCallbacks::DoCanShowCyberItem (Environment* ev, CyberItem* item)
  763. {
  764.     FW_UNUSED (ev);
  765.     FW_UNUSED (item);
  766.     
  767.     // This is a test for equality (not identity). If you are showing
  768.     // some variant of the given item, return true. For example,
  769.     // http://Where/ is similar to http://Where/index.html
  770.     // Also, http://Here#Bookmark is similar to http://Here
  771.     // You don't need to test for identity; it's been handled already.
  772.     
  773.     return FALSE;
  774. }
  775.  
  776. //-----------------------------------------------------------------------------
  777. // FW_CCyberdogCallbacks::DoShowCyberItem
  778. //-----------------------------------------------------------------------------
  779.  
  780. void FW_CCyberdogCallbacks::DoShowCyberItem (Environment* ev, CyberItem* item)
  781. {
  782.     FW_UNUSED (ev);
  783.     FW_UNUSED (item);
  784. }
  785.  
  786. //-----------------------------------------------------------------------------
  787. // FW_CCyberdogCallbacks::DoGetCyberItemWindow
  788. //-----------------------------------------------------------------------------
  789.  
  790. ODWindow* FW_CCyberdogCallbacks::DoGetCyberItemWindow (Environment* ev, CyberItem* item)
  791. {
  792.     FW_UNUSED (item);
  793.     
  794.     // I think this API is a Cyberdog bug: it is not acquiring the window!
  795.     // This is not properly thread-safe.
  796.     
  797.     FW_CFrame* probableFrame = fPart->GetLastActiveFrame (ev);
  798.     if (probableFrame) {
  799.         FW_TAcquiredODRefCntObject<ODWindow> theWindow = probableFrame->AcquireODWindow (ev);
  800.         return theWindow;
  801.     }
  802.     
  803.     return kODNULL;
  804. }
  805.  
  806. //-----------------------------------------------------------------------------
  807. // FW_CCyberdogCallbacks::DoIsCyberItemSelected
  808. //-----------------------------------------------------------------------------
  809.  
  810. ODBoolean FW_CCyberdogCallbacks::DoIsCyberItemSelected (Environment* ev, ODFrame* frame)
  811. {
  812.     FW_UNUSED (ev);
  813.     FW_UNUSED (frame);
  814.     
  815.     return FALSE;
  816. }
  817.  
  818. //-----------------------------------------------------------------------------
  819. // FW_CCyberdogCallbacks::DoAcquireSelectedCyberItems
  820. //-----------------------------------------------------------------------------
  821.  
  822. void FW_CCyberdogCallbacks::DoAcquireSelectedCyberItems (Environment* ev, ODFrame* frame, CyberItemList* items)
  823. {
  824.     FW_UNUSED (ev);
  825.     FW_UNUSED (frame);
  826.     FW_UNUSED (items);
  827. }
  828.  
  829. //-----------------------------------------------------------------------------
  830. // FW_CCyberdogCallbacks::DoIsURLSelected
  831. //-----------------------------------------------------------------------------
  832.  
  833. ODBoolean FW_CCyberdogCallbacks::DoIsURLSelected (Environment* ev, ODFrame* frame)
  834. {
  835.     FW_UNUSED (ev);
  836.     FW_UNUSED (frame);
  837.     
  838.     return FALSE;
  839. }
  840.  
  841. //-----------------------------------------------------------------------------
  842. // FW_CCyberdogCallbacks::DoGetSelectedURL
  843. //-----------------------------------------------------------------------------
  844.  
  845. void FW_CCyberdogCallbacks::DoGetSelectedURL (Environment* ev, ODFrame* frame, FW_CString & url)
  846. {
  847.     FW_UNUSED (ev);
  848.     FW_UNUSED (frame);
  849.     
  850.     url = "";
  851. }
  852.  
  853. //-----------------------------------------------------------------------------
  854. // FW_CCyberdogCallbacks::HandleCyberCommand
  855. //-----------------------------------------------------------------------------
  856.  
  857. ODBoolean FW_CCyberdogCallbacks::HandleCyberCommand (Environment* ev, long commandSuite, long command, ODFrame* frame, somToken parameters)
  858. {
  859.     // By default call the default ("inherited") HandleCommand in CyberPartExtension.
  860.     return fExtension->DefaultHandleCommand (ev, commandSuite, command, frame, parameters);
  861. }
  862.  
  863. //-----------------------------------------------------------------------------
  864. // FW_CCyberdogCallbacks::CreateCyberExtension
  865. //-----------------------------------------------------------------------------
  866.  
  867. ODExtension* FW_CCyberdogCallbacks::CreateCyberExtension (Environment* ev, FW_CPart* part, const char* name, void* selfCallbacks)
  868. {
  869.     FW_UNUSED (name);
  870.     
  871.     FW_CCyberdogCallbacks* self = (FW_CCyberdogCallbacks*) selfCallbacks;
  872.     
  873.     ODPart* odpart = part->GetODPart(ev);
  874.     ODF_FW_OCyberPartExtension* cyberPartExtension = new ODF_FW_OCyberPartExtension;
  875.     cyberPartExtension->ICyberPartExtension (ev, odpart);
  876.     cyberPartExtension->SetCallbacks (ev, self);
  877.     
  878.     // This is a bit odd. Basically a Cyberdog part has to be a client of its own extension,
  879.     // because that's the only way to talk to Cyberdog. Therefore once we create the
  880.     // extension, we don't let it go. Hence the unbalanced Acquire.
  881.     cyberPartExtension->Acquire(ev);
  882.     self->fExtension = cyberPartExtension;
  883.     
  884.     return cyberPartExtension;
  885. }
  886.  
  887. #pragma mark -
  888. //========================================================================================
  889. // Callbacks
  890. //========================================================================================
  891. #pragma mark Callbacks
  892.  
  893. //----------------------------------------------------------------------------------------
  894. // Callback Utilities
  895. //----------------------------------------------------------------------------------------
  896.  
  897. // Should I use RTTI here? Hardly seems necessary.
  898. #define FINDSELF(SELF,CALLBACKS)     FW_CCyberdogCallbacks* SELF = \
  899.                                     (FW_CCyberdogCallbacks*) CALLBACKS
  900.  
  901. //----------------------------------------------------------------------------------------
  902. // FW_CallbackOpenCyberItem
  903. //----------------------------------------------------------------------------------------
  904.  
  905. void         FW_CallbackOpenCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item, ODPart* openerPart, ParameterSet* data)
  906. {
  907.     FW_SOM_CALLBACK_TRY
  908.         FINDSELF(self,callbacks);
  909.         self->HandleOpenCyberItem (ev, item, openerPart, data);
  910.     FW_SOM_CALLBACK_ENDTRY
  911. }
  912.  
  913. //----------------------------------------------------------------------------------------
  914. // FW_CallbackSetCyberItem
  915. //----------------------------------------------------------------------------------------
  916.  
  917. void         FW_CallbackSetCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item, ParameterSet* data)
  918. {
  919.     FW_SOM_CALLBACK_TRY
  920.         FINDSELF(self,callbacks);
  921.         self->DoSetCyberItem (ev, item, data);
  922.     FW_SOM_CALLBACK_ENDTRY
  923. }
  924.  
  925. //----------------------------------------------------------------------------------------
  926. // FW_CallbackCanShowCyberItem
  927. //----------------------------------------------------------------------------------------
  928.  
  929. ODBoolean     FW_CallbackCanShowCyberItem     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  930. {
  931.     ODBoolean similar = false;
  932.     FW_SOM_CALLBACK_TRY
  933.         FINDSELF(self,callbacks);
  934.         similar = self->DoCanShowCyberItem (ev, item);
  935.     FW_SOM_CALLBACK_ENDTRY
  936.     
  937.     return similar;
  938. }
  939.  
  940. //----------------------------------------------------------------------------------------
  941. // FW_CallbackShowCyberItem
  942. //----------------------------------------------------------------------------------------
  943.  
  944. void         FW_CallbackShowCyberItem         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  945. {
  946.     FW_SOM_CALLBACK_TRY
  947.         FINDSELF(self,callbacks);
  948.         self->DoShowCyberItem (ev, item);
  949.     FW_SOM_CALLBACK_ENDTRY
  950. }
  951.  
  952. //----------------------------------------------------------------------------------------
  953. // FW_CallbackGetCyberItemWindow
  954. //----------------------------------------------------------------------------------------
  955.  
  956. ODWindow*     FW_CallbackGetCyberItemWindow     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, CyberItem* item)
  957. {
  958.     FW_SOM_CALLBACK_TRY
  959.         FINDSELF(self,callbacks);
  960.         return self->DoGetCyberItemWindow (ev, item);
  961.     FW_SOM_CALLBACK_ENDTRY
  962.     
  963.     return NULL;
  964. }
  965.  
  966. //----------------------------------------------------------------------------------------
  967. // FW_CallbackIsCyberItemSelected
  968. //----------------------------------------------------------------------------------------
  969.  
  970. ODBoolean     FW_CallbackIsCyberItemSelected     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame)
  971. {
  972.     ODBoolean selected = false;
  973.     
  974.     FW_SOM_CALLBACK_TRY
  975.         FINDSELF(self,callbacks);
  976.         selected = self->DoIsCyberItemSelected (ev, frame);
  977.     FW_SOM_CALLBACK_ENDTRY
  978.     
  979.     return selected;
  980. }
  981.  
  982. //----------------------------------------------------------------------------------------
  983. // FW_CallbackAcquireSelectedCyberItems
  984. //----------------------------------------------------------------------------------------
  985.  
  986. void         FW_CallbackAcquireSelectedCyberItems     (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame, CyberItemList* list)
  987. {
  988.     FW_SOM_CALLBACK_TRY
  989.         FINDSELF(self,callbacks);
  990.         self->DoAcquireSelectedCyberItems (ev, frame, list);
  991.     FW_SOM_CALLBACK_ENDTRY
  992. }
  993.  
  994. //----------------------------------------------------------------------------------------
  995. // FW_CallbackIsURLSelected
  996. //----------------------------------------------------------------------------------------
  997.  
  998. ODBoolean    FW_CallbackIsURLSelected         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame)
  999. {
  1000.     ODBoolean selected = false;
  1001.     
  1002.     FW_SOM_CALLBACK_TRY
  1003.         FINDSELF(self,callbacks);
  1004.         selected = self->DoIsURLSelected (ev, frame);
  1005.     FW_SOM_CALLBACK_ENDTRY
  1006.     
  1007.     return selected;
  1008. }
  1009.  
  1010. //----------------------------------------------------------------------------------------
  1011. // FW_CallbackGetSelectedURL
  1012. //----------------------------------------------------------------------------------------
  1013.  
  1014. void         FW_CallbackGetSelectedURL         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, ODFrame* frame, FW_CString& url)
  1015. {
  1016.     FW_SOM_CALLBACK_TRY
  1017.         FINDSELF(self,callbacks);
  1018.         self->DoGetSelectedURL (ev, frame, url);
  1019. #if 0
  1020.         // all this has been moved into SLCyPart.cpp
  1021.         int length = url.GetByteLength();
  1022.         if (length == 0)
  1023.             return NULL;
  1024.         corbastring curl = (corbastring) SOMMalloc (length + 1);
  1025.         if (!curl)
  1026.             FW_Failure(FW_xMemoryExhausted);
  1027.         strcpy (curl, url);
  1028.         return curl;
  1029. #endif
  1030.     FW_SOM_CALLBACK_ENDTRY
  1031. }
  1032.  
  1033. //----------------------------------------------------------------------------------------
  1034. // FW_CallbackHandleCommand
  1035. //----------------------------------------------------------------------------------------
  1036.  
  1037. ODBoolean     FW_CallbackHandleCommand         (Environment* ev, FW_SCyberPartExtensionCallbacks* callbacks, long commandSuite, long command, ODFrame* frame, somToken parameters)
  1038. {
  1039.     ODBoolean handled = false;
  1040.     
  1041.     FW_SOM_CALLBACK_TRY
  1042.         FINDSELF(self,callbacks);
  1043.         handled = self->HandleCyberCommand (ev, commandSuite, command, frame, parameters);
  1044.     FW_SOM_CALLBACK_ENDTRY
  1045.     
  1046.     return handled;
  1047. }
  1048.  
  1049.